package com.manager.core.module.manager.service;

import com.manager.commons.utils.StringUtil;
import com.manager.commons.base.DataGrid;
import com.manager.commons.mybatis.dao.GenericDao;
import com.manager.commons.mybatis.service.GenericService;
import com.manager.commons.utils.GetterSetterGenerator;
import com.manager.core.module.manager.entity.TableColumn;
import com.manager.core.module.manager.dao.PlatformParameterDao;
import com.manager.core.module.manager.dao.PlatformGeneratorDao;
import com.manager.core.module.manager.entity.PlatformParameter;
import com.manager.core.web.json.AjaxJson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

@Service
public class PlatformGeneratorService extends GenericService<TableColumn> {
    @Autowired
    private PlatformGeneratorDao tableMapper;

    @Autowired
    private PlatformParameterDao jdbcDao;


    public DataGrid querAll() {
        PlatformParameter platformParameter = jdbcDao.findCode("DBSetting");
        Map<String, Object> map = new HashMap<>();
        map.put("dbName", platformParameter.getValue_vc());
        List<TableColumn> list = tableMapper.getTablesByDbName(map);
        return new DataGrid(1000, list);
    }

    public AjaxJson save(Map<String, Object> params) {
        PlatformParameter platformParameter = jdbcDao.findCode("DBSetting");//获取到数据库名称
        String packageName = getParamsString(params, "packageName").trim();//包名
        String groupName = getParamsString(params, "groupName").trim();// 分组名
        if (StringUtil.isNotEmpty(groupName) && (groupName.indexOf("/") != 0 || groupName.lastIndexOf(".") != 0)) {
            groupName = "/" + groupName;
        }

        String dao = jdbcDao.findCode("GENRATOR_DAO").getValue_t(packageName, groupName);
        String mapping = jdbcDao.findCode("GENRATOR_MAPPING").getValue_t(packageName, groupName);
        String entity = jdbcDao.findCode("GENRATOR_ENTITY").getValue_t(packageName, groupName);
        String service = jdbcDao.findCode("GENRATOR_SERVICE").getValue_t(packageName, groupName);
        String controller = jdbcDao.findCode("GENRATOR_CONTROLLER").getValue_t(packageName, groupName);
        String html = jdbcDao.findCode("GENRATOR_INDEX").getValue_t();
        String edit = jdbcDao.findCode("GENRATOR_EDIT").getValue_t();
        String[] _idsArr = (String[]) params.get("_ids");//选择的表
        for (String _id : _idsArr) {
            Map<String, Object> map = new HashMap<>();
            map.put("dbName", platformParameter.getValue_vc());
            map.put("tableName", _id);
            TableColumn tablName = tableMapper.getTablesByTableName(map);
            String tableName = _id.toLowerCase();//统一转成小写
            String entityName_ = tableName.substring(tableName.lastIndexOf("_") + 1);//格式转行
            String entityName = StringUtil.toCapitalizeCamelCase(tableName);//toCapitalizeCamelCase("hello_world") == "HelloWorld"
            List<TableColumn> tableColumns = tableMapper.getTableStructure(map);
            StringBuilder importS = new StringBuilder();
            StringBuilder methods = new StringBuilder();
            StringBuilder attributes = new StringBuilder();
            StringBuilder sqlColumn = new StringBuilder();
            StringBuilder names = new StringBuilder();
            StringBuilder values = new StringBuilder();
            StringBuilder updateColumn = new StringBuilder();
            StringBuilder htmls = new StringBuilder();
            StringBuilder edits = new StringBuilder();
            for (TableColumn tableColumn : tableColumns) {
                String columnName = tableColumn.getColumnName().toLowerCase();
                String attributeName = StringUtil.toCamelCase(columnName);//toCamelCase("hello_world") == "helloWorld"
                String type = GetterSetterGenerator.getJavaType(tableColumn.getColumnType());
                //查询字段生成

                if (!columnName.equalsIgnoreCase("db_modifier") && !columnName.equalsIgnoreCase("db_modify_time")) {
                    sqlColumn.append(",").append(" a.").append(columnName).append(" as ");
                    if (columnName.equalsIgnoreCase("db_create_time")) {
                        sqlColumn.append(" createTime");
                    } else if (columnName.equalsIgnoreCase("db_creator")) {
                        sqlColumn.append(" creator");
                    } else if (columnName.equalsIgnoreCase("db_status")) {
                        sqlColumn.append(" _status");
                    } else {
                        sqlColumn.append(attributeName);
                        if (tableColumn.getColumn_Key().equalsIgnoreCase("PRI") && attributeName.equalsIgnoreCase("id")) {
                            sqlColumn.append(" ,a.").append(columnName).append(" as ").append(" _id");
                        }
                    }
                    if (!columnName.equalsIgnoreCase("id") && !columnName.equalsIgnoreCase("db_status") && !columnName.equalsIgnoreCase("db_creator") && !columnName.equalsIgnoreCase("db_create_time")) {
                        htmls.append(" {field: '").append(attributeName).append("'").append(", title: '").append(tableColumn.getColumnComment()).append("'").append("}").append(",").append("\n");
                        edits.append(" <div class=\"layui-form-item\">\n<label class=\"layui-form-label\">").append(tableColumn.getColumnComment());
                        edits.append("</label>\n<div class=\"layui-input-inline\">\n<input type=\"text\" name=\"").append(attributeName).append("\" placeholder=\"请输入").append(tableColumn.getColumnComment()).append("\"  class=\"layui-input\"");
                        edits.append(" value=\"${info.").append(attributeName).append("!}\">\n</div>\n</div>");
                        edits.append("\n");

                    }
                }
                if (!columnName.equalsIgnoreCase("db_modifier") && !columnName.equalsIgnoreCase("db_modify_time")) {
                    //以下两种类型需要引入对应类型包
                    if (type.equals("Date")) {
                        importS.append("\n").append("import java.util.Date;");
                    } else if (type.equals("BigDecimal")) {
                        importS.append("\n").append("import java.math.BigDecimal;");
                    }
                    if (!columnName.equalsIgnoreCase("db_create_time") && !columnName.equalsIgnoreCase("db_creator") && !columnName.equalsIgnoreCase("id") && !columnName.equalsIgnoreCase("db_status")) {
                        //根据名称生成对应的属性
                        attributes.append("\n").append(GetterSetterGenerator.generateAttribute(attributeName, type, tableColumn.getColumnComment()));
                        //生成Get set方法
                        methods.append("\n").append(GetterSetterGenerator.generateSetter(attributeName, type));
                        methods.append("\n").append(GetterSetterGenerator.generateGetter(attributeName, type));

                    }
                    names.append(",").append(columnName);
                    if (columnName.equalsIgnoreCase("db_create_time") || columnName.equalsIgnoreCase("db_creator") || columnName.equalsIgnoreCase("db_status")) {
                        if (columnName.equalsIgnoreCase("db_create_time")) {
                            values.append(",").append(" now() ");
                        } else if (columnName.equalsIgnoreCase("db_status")) {
                            values.append(",").append(" 1 ");
                        } else {
                            values.append(",").append(" #{creator}");
                        }
                    } else {
                        values.append(",").append(" #{").append(attributeName).append("}");
                    }
                    if (!columnName.equalsIgnoreCase("db_create_time") && !columnName.equalsIgnoreCase("db_creator") && !columnName.equalsIgnoreCase("db_status")) {
                        updateColumn.append(columnName).append("=#{").append(attributeName).append("},").append("\n");
                    }
                }

            }
            if (names.indexOf(",") == 0) names.delete(0, 1);
            if (values.indexOf(",") == 0) values.delete(0, 1);
            if (sqlColumn.indexOf(",") == 0) sqlColumn.delete(0, 1);
            TemplateDao(dao, packageName, groupName, entityName, tablName.getColumnComment());
            TemplateEntity(entity, packageName, groupName, entityName, tablName.getColumnComment(), importS.toString(), attributes.toString(), methods.toString());
            TemplateMapping(mapping, packageName, groupName, tableName, sqlColumn.toString(), entityName, names.toString(), values.toString(), updateColumn.toString());
            TemplateService(service, packageName, groupName, entityName, tablName.getColumnComment());
            TemplateController(controller, packageName, groupName, entityName, tablName.getColumnComment(), tableName.replace("_", "/"), entityName_);
            TemplateFtl(html, packageName, groupName, htmls.toString(), entityName_);
            TemplateEdit(edit, packageName, groupName, edits.toString(), entityName_);
        }

        return new AjaxJson(1, "生成成功");
    }

    private void TemplateEdit(String template, String packageName, String groupName, String edits, String entityName_) {
        String t = template.replace("#{edits}", edits);
        writ(t, "ftl", packageName, groupName, entityName_ + "-edit");

    }

    private void TemplateFtl(String template, String packageName, String groupName, String html, String entityName_) {
        String t = template.replace("#{html}", html);
        writ(t, "ftl", packageName, groupName, entityName_ + "-index");

    }

    /**
     * 生成Dao文件
     *
     * @param template
     * @param packageName
     * @param groupName
     * @param entityName
     */
    private void TemplateService(String template, String packageName, String groupName, String entityName, String columnComment) {
        String t = template.replace("#{entityName}", entityName).replace("#{columnComment}", columnComment);
        writ(t, "Service", packageName, groupName, entityName);

    }


    private void TemplateEntity(String template, String packageName, String groupName, String entityName, String columnComment, String imports, String attributes, String methods) {
        String t = template.replace("#{entityName}", entityName).replace("#{import}", imports).replace("#{columnComment}", columnComment).replace("#{attributes}", attributes).replace("#{methods}", methods);
        writ(t, "Entity", packageName, groupName, entityName);
    }

    /**
     * 生成Dao文件
     *
     * @param template
     * @param packageName
     * @param groupName
     * @param entityName
     */
    private void TemplateDao(String template, String packageName, String groupName, String entityName, String columnComment) {
        String t = template.replace("#{entityName}", entityName).replace("#{columnComment}", columnComment);
        writ(t, "Dao", packageName, groupName, entityName);
    }

    private void TemplateMapping(String template, String packageName, String groupPath, String talbeName, String sqlColumn, String entityName, String names, String values, String updateColumn) {
        String t = template.replace("#{entityName}", entityName).replace("#{sqlColumn}", sqlColumn).replace("#{talbeName}", talbeName).replace("#{names}", names).replace("#{values}", values).replace("#{updateColumn}", updateColumn);
        writ(t, "Mapping", packageName, groupPath, entityName);

    }


    /**
     * 生成Dao文件
     *
     * @param template
     * @param packageName
     * @param groupName
     * @param entityName
     */
    private void TemplateController(String template, String packageName, String groupName, String entityName, String columnComment, String tableName, String entityName_) {
        String t = template.replace("#{entityName}", entityName).replace("#{tableName_}", tableName).replace("#{title}", columnComment).replace("#{columnComment}", columnComment).replace("#{entityName_}", entityName_);
        writ(t, "Controller", packageName, groupName, entityName);
    }


    private void writ(String content, String type, String packageName, String groupPath, String entityName) {
        try {
            StringBuilder path = new StringBuilder();
            path.append("D://Generator/");
            //如果不是mapping 则创建目录
            if (!type.equalsIgnoreCase("mapping") && !type.equalsIgnoreCase("ftl")) {
                path.append(packageName.replace(".", "/"));
                path.append("/");
            }
            //根据类型创建不同的目录
            path.append(type.toLowerCase()).append("/");
            if (StringUtil.isNotEmpty(groupPath)) {
                path.append(groupPath.replace(".", "/"));
                path.append("/");
            }
            String daoPath = path.toString();
            File ymdFile = new File(daoPath);
            if (!ymdFile.exists()) {
                ymdFile.mkdirs();
            }
            StringBuilder filePath = new StringBuilder();
            filePath.append(daoPath).append("/").append(entityName);
            if (type.equalsIgnoreCase("Mapping")) {
                filePath.append(".xml");
            } else if (type.equalsIgnoreCase("ftl")) {
                filePath.append(".ftl");
            } else {
                if (!type.equalsIgnoreCase("Entity")) filePath.append(type);
                filePath.append(".java");
            }

            Files.write(
                    Paths.get(filePath.toString()),
                    Collections.singletonList(content),
                    StandardCharsets.UTF_8
            );

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public GenericDao<TableColumn> getDao() {
        return null;
    }
}
